/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.verolux.soft.debaraz.service;

import com.verolux.soft.debaraz.bean.UserContext;
import com.verolux.soft.debaraz.dao.UserDAO;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author ut1e8p
 */
@Service(value = "userDetailsService")
@Transactional(readOnly = true)
public class CustomUserDetailsService implements UserDetailsService {

    private static Logger logger = Logger.getLogger(CustomUserDetailsService.class);

    @Autowired
    private UserDAO userDAO;

    /**
     * 
     * @param username
     * @return
     * @throws UsernameNotFoundException
     * @throws DataAccessException
     */
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
        // Declare a null Spring User
        UserDetails user = null;

        try {

            // Search database for a user that matches the specified username
            // You can provide a custom DAO to access your persistence layer
            // Or use JDBC to access your database
            // DbUser is our custom domain user. This is not the same as Spring's User

            com.verolux.soft.debaraz.bean.User dbUser = userDAO.findByEmail(username);

            if (dbUser != null) {
                // Populate the Spring User object with details from the dbUser
                // Here we just pass the username, password, and access level
                // getAuthorities() will translate the access level to the correct role type
                user = new UserContext(
                        dbUser.getEmail(),
                        dbUser.getPassword().toLowerCase(),
                        true,
                        true,
                        true,
                        true,
                        getAuthorities(dbUser.getUserRole()),
                        dbUser
                        );
            } 

        } catch (Exception e) {
            logger.error("Error in retrieving user");
            throw new UsernameNotFoundException("Error in retrieving user");
        }

        // Return user to Spring for processing.
        // Take note we're not the one evaluating whether this user is authenticated or valid
        // We just merely retrieve a user that matches the specified username
        return user;

    }

    /**
     *
     * @param access
     * @return
     */
    public Collection<GrantedAuthority> getAuthorities(com.verolux.soft.debaraz.bean.User.USER_ROLE userRole) {
        // Create a list of grants for this user
        List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>(1);

        // Check if this user has admin access
        // We interpret Integer(1) as an admin user
        if (userRole.equals(com.verolux.soft.debaraz.bean.User.USER_ROLE.ADMIN)) {
            // User has admin access
            authList.add(new GrantedAuthorityImpl("ROLE_ADMIN"));
        } else {
            // User has admin access
            authList.add(new GrantedAuthorityImpl("ROLE_USER"));
        }

        // Return list of granted authorities
        return authList;
    }
}
